package com.tanhua.dubbo.server.api.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.dubbo.server.api.HuanXinApi;
import com.tanhua.dubbo.server.config.HuanXinConfig;
import com.tanhua.dubbo.server.enums.HuanXinMessageType;
import com.tanhua.dubbo.server.mapper.HuanXinUserMapper;
import com.tanhua.dubbo.server.pojo.HuanXinUser;
import com.tanhua.dubbo.server.service.RequestService;
import com.tanhua.dubbo.server.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.Date;

@Service(version = "1.0.0")
@Slf4j
public class HuanXinApiImpl implements HuanXinApi {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private HuanXinConfig huanXinConfig;

    @Autowired
    private RequestService requestService;

    @Autowired
    private HuanXinUserMapper huanXinUserMapper;

    /**
     * 获取环信token（获取管理员权限）
     *
     * @return
     */
    @Override
    public String getToken() {
        return this.tokenService.getToken();
    }

    /**
     * 注册环信账号
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public Boolean register(Long userId) {
        String targetUrl = this.huanXinConfig.getUrl() + this.huanXinConfig.getOrgName()
                + "/" + this.huanXinConfig.getAppName() + "/users";
        HuanXinUser huanXinUser = new HuanXinUser();
        huanXinUser.setUsername("HX_" + userId);
        huanXinUser.setPassword(IdUtil.simpleUUID()); //随机生成密码

        HttpResponse response = this.requestService.execute(targetUrl, JSONUtil.toJsonStr(Arrays.asList(huanXinUser)), Method.POST);
        if (response.isOk()) {
            //将环信账号保存到数据库中
            huanXinUser.setUserId(userId);
            huanXinUser.setCreated(new Date());
            huanXinUser.setUpdated(huanXinUser.getCreated());

            this.huanXinUserMapper.insert(huanXinUser);

            return true;
        }
        return false;
    }

    /**
     * 根据id查询环信账号信息
     *
     * @param userId
     * @return
     */
    @Override
    public HuanXinUser queryHuanXinUser(Long userId) {

        QueryWrapper<HuanXinUser> query = new QueryWrapper<>();
        query.eq("user_id", userId);
        HuanXinUser huanXinUser = this.huanXinUserMapper.selectOne(query);
        return huanXinUser;
    }

    /**
     * 根据环信用户名查询用户信息
     *
     * @param userName
     * @return
     */
    @Override
    public HuanXinUser queryUserByUserName(String userName) {
        QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", userName);
        HuanXinUser huanXinUser = this.huanXinUserMapper.selectOne(wrapper);
        return huanXinUser;
    }

    /**
     * 添加环信中好友的关系
     *
     * @param userId   自己的id
     * @param friendId 好友的id
     * @return
     */
    @Override
    public Boolean addUserFriend(Long userId, Long friendId) {

        String targetUrl = this.huanXinConfig.getUrl() + this.huanXinConfig.getOrgName()
                + "/" + this.huanXinConfig.getAppName() + "/users/HX_" + userId +
                "/contacts/users/HX_" + friendId;

        try {
            // 404 -> 对方未在环信注册
            HttpResponse response = this.requestService.execute(targetUrl, null, Method.POST);
            return response.isOk();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //添加失败
        return false;
    }

    /**
     * 删除环信中好友的关系
     *
     * @param userId   自己的id
     * @param friendId 好友的id
     * @return
     */
    @Override
    public Boolean removeUserFriend(Long userId, Long friendId) {
        String targetUrl = this.huanXinConfig.getUrl() + this.huanXinConfig.getOrgName()
                + "/" + this.huanXinConfig.getAppName() + "/users/HX_" + userId +
                "/contacts/users/HX_" + friendId;

        try {
            // 404 -> 对方未在环信注册
            HttpResponse response = this.requestService.execute(targetUrl, null, Method.DELETE);
            return response.isOk();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //删除失败
        return false;
    }

    /**
     * 回复陌生人信息
     *
     * @param targetUserName     发送目标的用户名
     * @param huanXinMessageType 消息类型
     * @param msg
     * @return
     */
    @Override
    public Boolean sendMsgFromAdmin(String targetUserName, HuanXinMessageType huanXinMessageType, String msg) {
        ///{org_name}/{app_name}/messages
        String targetUrl = this.huanXinConfig.getUrl() +
                this.huanXinConfig.getOrgName() + "/" +
                this.huanXinConfig.getAppName() + "/messages";
        /*
        target_type	发送的目标类型；users：给用户发消息，
        chatgroups：给群发消息，chatrooms：给聊天室发消息
        target	发送的目标；注意这里需要用数组，数组内添加的最大用户数默认600个，
        即使只有一个用户，也要用数组 ['u1']；给用户发送时数组元素是用户名，
        给群组发送时，数组元素是groupid
        msg	消息内容
        type	消息类型；txt:文本消息，img：图片消息，loc：位置消息，
        audio：语音消息，video：视频消息，file：文件消息
        from	表示消息发送者;无此字段Server会默认设置为“from”:“admin”，
        有from字段但值为空串(“”)时请求失败
         */
        try {
            String body = JSONUtil.createObj()
                    .set("target_type", "users")
                    .set("target", JSONUtil.createArray().set(targetUserName))
                    .set("msg", JSONUtil.createObj()
                            .set("type", huanXinMessageType.getType())
                            .set("msg", msg))
                    .set("from", "from").toString();
            HttpResponse response = this.requestService.execute(targetUrl, body, Method.POST);
            if (response.isOk()) {
                return true;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }


}